package com.eorchis.module.security.cas.filter;

import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.security.web.FilterInvocation;
import org.springframework.util.StringUtils;
import com.eorchis.core.springext.mvc.SessionConstant;
import com.eorchis.module.department.domain.Department;
import com.eorchis.module.security.cas.domain.DomainFactory;
import com.eorchis.module.security.cas.domain.Role;
import com.eorchis.module.security.cas.domain.Systems;
import com.eorchis.utils.utils.DynamicGetUrl;
import com.eorchis.utils.utils.XMLHelper;

/**
 * Title: CasResponseParse<br>
 * Description: CAS解析类<br>
 * Copyright @ 2011~2013 Goldgov .All rights reserved.<br>
 * 
 * @author GuoR
 * @createDate 2013-3-9
 * @version $Revision: $
 */
public class CasResponseParseImpl implements ICasResonseParse {
	private DomainFactory domainFactory;

	public void berforParseCasResponse(FilterInvocation fi) {

	}

	public void afterParseCasResponse(String casServerXml, HttpServletRequest request) {
		HttpSession session = request.getSession();
		// 转换department对象，加入特定编码。
		com.eorchis.module.security.cas.domain.Department department = (com.eorchis.module.security.cas.domain.Department) session.getAttribute(SessionConstant.CURRENT_DEPARTMENT);
		if (department.getCountiesCoding() != null && !"".equals(department.getCountiesCoding())) {
			session.setAttribute(SessionConstant.CURRENT_PLATFORM_CODE, department.getCountiesCoding());
		} else {
			session.setAttribute(SessionConstant.CURRENT_PLATFORM_CODE, "01001");
		}
	}

	@SuppressWarnings("unchecked")
	public void parseCasResponse(String casServerXml, HttpServletRequest request) throws Exception {
		HttpSession session = request.getSession();
		session.setAttribute("LoginDate", new Date());

		List<Role> roles = new ArrayList<Role>();
		List<Department> scopes = new ArrayList<Department>();
		List<Systems> systems = new ArrayList<Systems>();

		boolean hasSystem = false;
		/*
		 * 调用前已判断userInfo为空，此处不再需要判断 modify by GuoR at 2013-02-18
		 */
		// if (userInfo == null) {
		ByteArrayInputStream bis = new ByteArrayInputStream(casServerXml.getBytes("UTF-8"));
		Document document = XMLHelper.load_Document(bis);
		Element rootElement = document.getRootElement();
		Element userElement = rootElement.element("user");
		Element curDepElement = userElement.element("department");

//		String requestURL = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
		Iterator<Element> systemElementIter = userElement.elementIterator("system");

		while (systemElementIter.hasNext()) {
			Element systemElement = systemElementIter.next();
			// CasSystems tempSystem = (CasSystems)
			// XMLHelper.getElementObject(systemElement, new CasSystems());
			/*
			 * 直接读取systemURL属性，不需要再创建system对象,并对URL进行Decoder modify by GuoR at
			 * 2013-02-18
			 */
//			String tempSystemURL = XMLHelper.getSingleChildElementValue(systemElement, "systemURL");
			// tempSystem.getSystemURL();
//			tempSystemURL = URLDecoder.decode(tempSystemURL, "UTF-8");

//			String tempSystemURLChanged = DynamicGetUrl.getUrl(tempSystemURL, request);
//			if (tempSystemURLChanged.indexOf(requestURL) == -1) {
//				continue;
//			} else {
				hasSystem = true;
//			}

			Iterator<Element> roleIter = systemElement.elementIterator("role");
			while (roleIter.hasNext()) {
				Element roleElement = roleIter.next();
				Iterator<Element> scopeIter = roleElement.elementIterator("scope");
				List<Department> roleScopes = new ArrayList<Department>();
				while (scopeIter.hasNext()) {
					Element scopeElem = scopeIter.next();
					Department dep = (Department) XMLHelper.getElementObject(scopeElem, domainFactory.createDepartmentObject());
					scopes.add(dep);
					roleScopes.add(dep);
				}
				// FIXME
				// 系统中默认的ROLE没有管理范围（scopes[department]）,因此扩展出一个com.eorchis.module.security.cas.domain.Role
				Role userRole = (Role) XMLHelper.getElementObject(roleElement, domainFactory.createRoleObject());
				userRole.setScopes(roleScopes);
				roles.add(userRole);
			}
			Systems system = (Systems) XMLHelper.getElementObject(systemElement, new Systems());
			system.setSystemURL(DynamicGetUrl.getUrl(system.getSystemURL(), request));
			systems.add(system);
		}
		com.eorchis.module.user.domain.User user = (com.eorchis.module.user.domain.User) XMLHelper.getElementObject(userElement, domainFactory.createUserObject());
		Department department = (Department) XMLHelper.getElementObject(curDepElement, domainFactory.createDepartmentObject());

		if (hasSystem) {
			session.setAttribute(SessionConstant.CURRENT_DEPARTMENT, department);
			session.setAttribute(SessionConstant.SYSTEMS, systems);
			session.setAttribute(SessionConstant.SCOPES, scopes);
			if (scopes.size() == 1) {
				session.setAttribute(SessionConstant.CURRENT_ROLE, scopes.get(0));
			}
			session.setAttribute(SessionConstant.ROLES, roles);
			if (roles.size() == 1) {
				session.setAttribute(SessionConstant.CURRENT_ROLE, roles.get(0));
			}
		}
		session.setAttribute(SessionConstant.USER_INFO, user);
		// modify by HuangS at 2013-01-10 提取部门入session系统外
		session.setAttribute(SessionConstant.CURRENT_DEPARTMENT, department);

		// FIXME 固定系统平台编码，以后动态获取或从SSO中获取
		session.setAttribute(SessionConstant.CURRENT_PLATFORM_CODE, "01001");

	}

	private String getResourceType(HttpServletRequest request) {
		String contextPath = request.getContextPath();
		String requestURI = request.getRequestURI();
		String pathInfo = StringUtils.replace(requestURI, contextPath, "");
		return pathInfo;
	}

	public DomainFactory getDomainFactory() {
		return domainFactory;
	}

	public void setDomainFactory(DomainFactory domainFactory) {
		this.domainFactory = domainFactory;
	}
}
